// node promise_demo.js
// npx babel-node promise_demo.js

let _ = "";
const {log} = console;

let test1 = function(){
    let timeout = function(ms){
        return new Promise((resolve, reject) => {
            setTimeout(resolve, ms, 'done');
        });
    };

    timeout(100).then((value) => {
        log(value);
    });
};
// test1();

// Promise 新建后就会立即执行。

let test2 = function(){
    let promise = new Promise(function(resolve, reject){
        log('Promise');
        resolve();
    });

    promise.then(function(){
        log('resolved.');
    });

    log('Hi');
};
// test2();

// 下面是异步加载图片的例子。

function loadImageAsync(url) {
    return new Promise(function(resolve, reject){
        const image = new Image();

        image.onload = function(){
            resolve(image);
        };

        image.onerror = function(){
            reject(new Error('Could not load image at ' + url));
        };

        image.src = url;
    });
}

// 下面是一个用Promise对象实现的 Ajax 操作的例子。

let test3 = function(){
    const getJson = function(url){
        const promise = new Promise(function(resolve, reject){
            const handler = function(){
                if (this.readyState !== 4) {
                    return;
                }
                if (this.status === 200) {
                    resolve(this.response);
                } else {
                    reject(new Error(this.statusText));
                }
            };
            const client = new XMLHttpRequest();
            client.open("GET", url);
            client.onreadystatechange = handler;
            client.responseType = "json";
            client.setRequestHeader("Accept", "application/json");
            client.send();
        });
        return promise;
    };

    getJson("/posts.json").then(function(json){
        log('Contents: ' + json);
    }, function(error){
        console.error('出错了', error);
    });
};

let test4 = function(){
    const p1 = new Promise(function(resolve, reject){
        setTimeout(() => reject(new Error('fail')), 3000);
    });

    const p2 = new Promise(function(resolve, reject){
        setTimeout(() => resolve(p1), 1000);
    });

    p2.then(result => log(result))
        .catch(error => log(error));
};
// test4();

let test5 = function(){
    new Promise((resolve, reject) => {
        resolve(1);
        log('aa');
    }).then(r => {
        log(r);
    });
};
// test5();

// 一般来说，调用resolve或reject以后，Promise 的使命就完成了，后继操作应该放到then方法里面，而不应该直接写在resolve或reject的后面。所以，最好在它们前面加上return语句，这样就不会有意外。

let test6 = function(){
    new Promise((resolve, reject) => {
        return resolve(1);
        log('aa');
    }).then(r => {
        log(r);
    });
};
// test6();

// 下面代码中，setTimeout(fn, 0)在下一轮“事件循环”开始时执行，Promise.resolve()在本轮“事件循环”结束时执行，console.log('one')则是立即执行，因此最先输出。

let test7 = function(){
    setTimeout(function(){
        log('three');
    }, 0);
    
    Promise.resolve().then(function(){
        log('two');
    });

    log('one');
};
test7();








